package controllers;

import java.util.Collection;

import javax.validation.Valid;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

import services.EvaluationService;
import services.ParticipantService;
import services.RouteService;
import domain.Evaluation;
import domain.Participant;
import domain.Route;

@Controller
@RequestMapping("/evaluation/participant")
public class EvaluationParticipantController extends AbstractController{

	// Supporting services -------------------------------------------------
	@Autowired
	private EvaluationService evaluationService;
	
	@Autowired
	private ParticipantService participantService;
	
	@Autowired
	private RouteService routeService;
	
	// Constructor ---------------------------------------------------------
	public EvaluationParticipantController(){
		super();
	}
	
	// Controller methods --------------------------------------------------
	@RequestMapping("/list")
	public ModelAndView list(){
		ModelAndView res;
		
		Participant principal;
		Collection<Evaluation> evaluations;
		
		principal = this.participantService.findByPrincipal();
		evaluations = this.evaluationService.findAllByParticipant(principal);
		
		res = new ModelAndView("evaluation/list");
		res.addObject("evaluations",evaluations);
		res.addObject("requestURI", "/evaluation/participant/list.do");
		
		return res;
	}
	
	@RequestMapping(value = "/create", method = RequestMethod.GET)
	public ModelAndView create(@RequestParam int routeId) {
		ModelAndView result;
		Route route = this.routeService.findOne(routeId);
		Evaluation evaluation = this.evaluationService.create(route);
		System.out.println("Llega a crear evaluation");
		result = createEditModelAndView(evaluation);
		result.addObject("create", true);

		return result;
	}
	
	
	
	@RequestMapping(value="/edit", method=RequestMethod.GET)
	public ModelAndView edit(@RequestParam int evaluationId){
		ModelAndView res;
		Evaluation evaluation = this.evaluationService.findOne(evaluationId);
		
		res = createEditModelAndView(evaluation);
		return res;
	}
	
	
	@RequestMapping(value="/edit", method=RequestMethod.POST, params="save")
	public ModelAndView save(@Valid Evaluation evaluation, BindingResult bindingResult){
		ModelAndView res;
		
		if(bindingResult.hasErrors()&&!evaluationService.itsHacked(evaluation)){
			if(bindingResult.getErrorCount()!=1)
			{
			res = createEditModelAndView(evaluation);
			}
			else{
				try{
					res = persist(evaluation);
				}
				catch(Exception oops){
					res = createEditModelAndView(evaluation,"evaluation.commit.error");
				}
			}
		}
		else if(evaluationService.itsHacked(evaluation)){
			res = createEditModelAndView(evaluation);
		}
		else{
			try{
				res = persist(evaluation);
			}
			catch(Exception oops){
				res = createEditModelAndView(evaluation,"evaluation.commit.error");
			}
		}
		
		return res;
	}

	@RequestMapping(value="/edit", method=RequestMethod.POST, params="delete")
	public ModelAndView delete(Evaluation evaluation, BindingResult bindingResult){
		ModelAndView res;
		
		try{
			Evaluation toDelete;
			toDelete= evaluationService.findOne(evaluation.getId());
			this.evaluationService.delete(toDelete);
			res = new ModelAndView("redirect:/evaluation/participant/list.do");
		}
		catch(Exception oops){
			res = createEditModelAndView(evaluation,"evaluation.commit.error");
		}
		
		return res;
	}
	
	// Ancillary methods ---------------------------------------------------
	protected ModelAndView createEditModelAndView(Evaluation evaluation) {
		ModelAndView result;

		result = createEditModelAndView(evaluation, null);

		return result;
	}

	protected ModelAndView createEditModelAndView(Evaluation evaluation, String message) {
		ModelAndView result;
		result = new ModelAndView("evaluation/edit");
		result.addObject("evaluation", evaluation);
		if(evaluation.getId()!=0)
		{
			result.addObject("create", true);
		}
		result.addObject("message", message);
		return result;
	}
	
	private ModelAndView persist(Evaluation evaluation){
		ModelAndView res;
		Evaluation toPersist;
		if(evaluation.getId()!=0){
		toPersist = evaluationService.findOne(evaluation.getId());
		toPersist.setAssessment(evaluation.getAssessment());
		}
		else
		{
			toPersist = evaluationService.create(evaluation.getRoute());
			toPersist.setAssessment(evaluation.getAssessment());
		}
		
		evaluationService.save(toPersist);
		res = new ModelAndView("redirect:/evaluation/participant/list.do");
		
		return res;
	}
}
